/* eslint-disable */
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import Empty from '../Empty';
import classnames from 'classnames';
import { getArrayByLevelAndId, DataType } from '@/utils';
import Popup from '../Popup';
import './index.less';

// type DataType = {
//   label: string
//   value: string | number
//   children: DataType[]
//   [propsName: string]: any
// }

type ValueType = {
  label: string;
  value: string | number;
};

interface LevelSelectProps {
  visible: boolean;
  onOk: (value: ValueType[]) => void;
  onCancel?: () => void;
  level?: number; // 默认3级
  placeholders?: string[]; // 输入框占位文本
  value?: ValueType[];
  mustAllSelected?: boolean; // 是否必须全部选中
  dataSource?: DataType[]; //
  fetchData?: (current: number, selected, value) => DataType[]; // 动态获取数据 level级别，从0开始, selected选中的值;value 已经选中的值
  title?: string | React.ReactNode;
  notFoundContent?: string; // 当下拉列表为空时显示的内容
  children?: React.ReactNode;
}

const LevelSelect: React.FC<LevelSelectProps> = (props: LevelSelectProps) => {
  const [visible, setVisible] = useState(props.visible); // 显隐
  const [cacheData, setCacheData] = useState({}); // 无数据源时的缓存数据
  const [options, setOptions] = useState([]); // 当前显示的下拉选项
  const [value, setValue] = useState(props.value || []); // 选中的值
  const [current, setCurrent] = useState(0);
  const placeholders = useRef([]);

  /**
   * form的this.props.value 同步state的value
   */
  useEffect(() => {
    if (JSON.stringify(props.value) !== JSON.stringify(value)) {
      const newValue = props.value || [];
      setValue(newValue);
      setCurrent(newValue.length > 0 ? newValue.length - 1 : 0);
    }
  }, [props.value]);

  /**
   * useCallback
   */
  // 格式化选中值的文案显示
  const formatSelectedString = useCallback(() => {
    const level = props.level;
    let valueString = props.placeholders ? props.placeholders : new Array(level).fill('请选择');
    if (valueString.length > level) {
      valueString = valueString.slice(0, level);
    } else if (valueString.length < level) {
      valueString = [...valueString, ...new Array(level - valueString.length).fill('请选择')];
    }
    placeholders.current = [...valueString];
    if (value) {
      value.forEach(({ label }, index) => {
        valueString[index] = label;
      });
    }
    // console.log('formatSelectedString-->', valueString, value)
    return [...valueString];
  }, [value, props.level]);

  // 从dataSource中拿对应数据
  const getOptionsByDataSource = useCallback(
    (key, current, value) => {
      if (key !== '' && cacheData[key]) {
        // 缓存中如果存在直接返回数据
        return cacheData[key];
      }
      return getArrayByLevelAndId(
        props.dataSource,
        value.map((it) => it.value),
        current,
      );
    },
    [props.dataSource, cacheData],
  );
  // 无数据源的情况，调用接口拿返回数据
  const getOptionsByFetchOrCache = useCallback(
    async (key, current, selected, value) => {
      if (key !== '' && cacheData[key]) {
        // 缓存中如果存在直接返回数据
        return cacheData[key];
      }
      const data = await props.fetchData(current, selected, value);
      if (data && Array.isArray(data)) {
        setCacheData(() => ({ ...cacheData, [key]: data }));
        return data;
      }
      return [];
    },
    [cacheData],
  );
  // 格式化选项值列表
  const formatSelectOptions = useCallback(async () => {
    const key = value
      .slice(0, current)
      .map((it) => it.value)
      .join('-');
    let newOptions = [];
    if (props.dataSource) {
      newOptions = getOptionsByDataSource(key, current, value);
    } else {
      // console.log('-->', key, value, current, value[current - 1])
      newOptions = await getOptionsByFetchOrCache(key, current, value[current - 1], value);
    }
    setOptions(newOptions);
  }, [current, props.dataSource, value]);

  // option click
  const onClick = useCallback(
    (item: ValueType) => {
      const level = props.level;
      const newValue = [...value].slice(0, current);
      newValue[current] = item;
      setValue(newValue);
      if (current < level - 1) {
        setCurrent(current + 1);
      } 
      if (current === level - 1){
        setCurrent(0);
      }
    },
    [props.level, current],
  );
  // selected click
  const toggle = useCallback(
    (current) => {
      if (value[current])
        // 有值才可以切换
        setCurrent(current);
    },
    [value],
  );

  // 点击确定
  const onOk = useCallback(() => {
    const { level, mustAllSelected } = props;
    if (mustAllSelected && value.length !== level) {
      return false;
    }

    if (typeof props.onOk === 'function') props.onOk(value);
  }, [props.onOk, value]);

  // 点击取消
  const onCancel = useCallback(() => {
    if (typeof props.onCancel === 'function') {
      props.onCancel();
      setValue(props.value || []);
      setCurrent(0);
    }
  }, [props.value, props.onCancel]);

  /**
   * useEffect
   */
  // 显隐控制
  useEffect(() => {
    setVisible(props.visible);
  }, [props.visible]);
  // 当current发生变化时，触发options的更新
  useEffect(() => {
    formatSelectOptions();
  }, [current]);
  const selectValuesString = [...formatSelectedString()];
  return (
    <Popup
      visible={visible}
      title={props.title as any}
      onOk={onOk}
      onClose={onCancel}
      onDismiss={onCancel}
      className="hr-level-select-popup"
    >
      <div className="hr-level-select-container">
        <div className="hr-level-select-values">
          {selectValuesString.map((label, index) => {
            return (
              <div
                onClick={() => toggle(index)}
                key={`${label}-${index}`}
                className={classnames('hr-level-select-value', {
                  'hr-level-select-value-selected': index === current,
                  'hr-level-has-value': label !== placeholders.current[index],
                })}
              >
                <span className="hr-level-select-value-label">{label}</span>
                {index !== selectValuesString.length - 1 && <i className="hr-value-line">/</i>}
              </div>
            );
          })}
        </div>
        <div className="hr-level-select-content">
          {options && options.length > 0 ? (
            options.map((item: ValueType) => {
              return (
                <div
                  className={classnames({
                    'hr-level-select-option-selected': (value[current] || {}).value === item.value,
                  })}
                  onClick={() => onClick(item)}
                  key={`${item.label}-${item.value}`}
                >
                  <div className="hr-level-select-content-item">{item.label}</div>
                </div>
              );
            })
          ) : (
            <Empty title={props.notFoundContent} />
          )}
        </div>
      </div>
      {props.children && ''}
    </Popup>
  );
};
LevelSelect.defaultProps = {
  level: 3,
  mustAllSelected: true,
  notFoundContent: '暂无数据',
};
export default LevelSelect;
